import {
    _decorator,
    Button,
    Component,
    director,
    instantiate,
    Label,
    Layout,
    Node,
    Prefab,
    ProgressBar,
    resources,
    Sprite,
    SpriteFrame,
    tween,
    Vec2,
    Vec3
} from 'cc';
import {userInfo} from '../../user-info';
import {HeadComp} from '../mainui/head-comp';
import {showAlert} from '../alert/alert';
import {GameEvent} from '../../game-event';
import {Peculiarity} from "db://assets/script/game/skills/peculiarity";
import {FishStatus} from '../../../proto/shared/v1/biz';
import {FreshImmortal} from "db://assets/proto/shared/v1/wuni";
import {serverTimeHelper} from "db://assets/script/server-time-helper";
import {configsHelper} from "db://assets/script/configs-helper";
import {fishUtils} from "db://assets/script/utils/fish-utils";
import {UserFishRefineEvent} from "db://assets/script/common/events/fish-events/user-fish-refine-event";
import {FishSleepEvent} from "db://assets/script/common/events/fish-events/fish-sleep-event";
import {lobby} from "db://assets/script/lobby";
import {PropBag} from "db://assets/script/game/mainui/props/prop-bag";
import {BagType} from "db://assets/script/game/constants/bag-type";
import Long from "long";
import {ZoneMapPlane} from "db://assets/script/game/mainui/battle/zone-map-plane";
import {FishAliveDurationSelector} from "db://assets/script/game/mainui/battle/fish-alive-duration-selector";
import {UserFishReceiveBagEvent} from "db://assets/script/common/events/fish-events/user-fish-receive-bag-event";
import {RadarChart} from "db://assets/script/game/mainui/radar-chart";
import {cmm} from "db://assets/script/utils/cmm";
import {textUtils} from "db://assets/script/utils/text-utils";
import {FishAttrsDetails} from "db://assets/script/game/mainui/fish-attrs-details";
import maxNormalHealth = fishUtils.maxNormalHealth;
import maxMagicPower = fishUtils.maxMagicPower;
import Tuple2 = cmm.Tuple2;
import {PropDesc} from "db://assets/script/game/mainui/props/prop-desc";

const {ccclass, property} = _decorator;

@ccclass('FishInfoComp')
export class FishInfoComp extends Component {
    @property(Node)
    close!: Node;

    @property(HeadComp)
    head!: HeadComp;

    @property(Label)
    nameLb!: Label;

    @property(Sprite)
    genderIcon!: Sprite;

    @property(Label)
    masterLabel!: Label

    @property(Label)
    ageLb!: Label;

    @property(Label)
    talentLb!: Label;

    @property(Label)
    personalityLb!: Label;

    @property(Node)
    lingGenBox!: Node;

    @property(Node)
    firstLingGen!: Node

    @property(Node)
    secondLingGen!: Node

    @property(Layout)
    peculiarityBox!: Layout;

    @property(Label)
    levelLabel!: Label;

    @property(ProgressBar)
    hpPb!: ProgressBar;

    @property(Label)
    hpLb!: Label;

    @property(ProgressBar)
    mpPb!: ProgressBar;

    @property(Label)
    mpLb!: Label;

    @property(ProgressBar)
    expPb!: ProgressBar;

    @property(Label)
    expLb!: Label;

    @property(Node)
    btnLianhua!: Node;

    @property(Node)
    btnjihuo!: Node;

    @property(Node)
    btnChange!: Node;

    @property(Node)
    chenshui!: Node;

    @property(RadarChart)
    dimRadarChart!: RadarChart;

    @property(Label)
    hsLabel!: Label;

    @property(Label)
    hcLabel!: Label;

    @property(Label)
    leftEyeColors!: Label;

    @property(Label)
    rightEyeColors!: Label;

    @property(Label)
    skinLabel!: Label;

    @property(Button)
    fishBagBtn!: Button

    @property(Button)
    zoneMapBtn!: Button;

    @property(Button)
    protectBtn!: Button

    @property(Label)
    attackLabel!: Label

    @property(Label)
    specialAttackLabel!: Label;

    @property(Label)
    defenceLabel!: Label;

    @property(Label)
    specialDefenceLabel!: Label

    @property(Label)
    recoverLabel!: Label;

    @property(FishAttrsDetails)
    fishAttrsDetails!: FishAttrsDetails;

    @property(Button)
    closeAttrsDetailsBtn!: Button;

    @property(Button)
    openAttrsDetailsBtn!: Button;

    @property(Prefab)
    tipsPrefab!: Prefab

    fish!: FreshImmortal
    zoneId!: Long
    showBtn: boolean = false;

    fishBag: PropBag | null = null;

    start() {
        this.onEvent();
    }

    onEvent() {
        this.openAttrsDetailsBtn.node.on(Button.EventType.CLICK, () => this.fishAttrsDetails.node.active = true)
        this.closeAttrsDetailsBtn.node.on(Button.EventType.CLICK, () => this.fishAttrsDetails.node.active = false)
        this.close.on(Node.EventType.TOUCH_END, () => this.node.destroy())
        this.btnLianhua.on(Button.EventType.CLICK, () => {
            showAlert("安葬", "您确定要安葬这个弟子吗？", () => {
                if (Object.keys(this.fish.assetInfo!.props).length > 0) {
                    showAlert('道具领取', '弟子行囊还有道具未领取，是否领取？', () => {
                        director.emit(GameEvent.userFishRequestReceiveFishBag, new UserFishReceiveBagEvent(this.fish.id, this.fish.zoneId.toString(), null, () => {
                            director.emit(GameEvent.userFishActionRefine, new UserFishRefineEvent(this.fish.id))
                        }))
                    })
                } else {
                    director.emit(GameEvent.userFishActionRefine, new UserFishRefineEvent(this.fish.id))
                }
            })
        })

        this.chenshui.on(Button.EventType.CLICK, () => {
            showAlert("召回宗门", "您确定要召回这个弟子吗？", () => {
                director.emit(GameEvent.fishActionSleep, new FishSleepEvent(this.fish.id, this.zoneId))
            })
        })
        this.btnjihuo.on(Button.EventType.CLICK, () => {
            showAlert("探索", "您确定要派遣这个弟子去探索吗？", async () => {
                const aliveDurationSelector = lobby.instance.addUIWithClickMask('prefab/common/fish-alive-duration-selector', 0, (node) => node.destroy())
                aliveDurationSelector.getComponent(FishAliveDurationSelector)!.init(this.fish.id, this.zoneId)
            })
        })

        this.btnChange.on(Button.EventType.CLICK, () => {
            director.emit(GameEvent.changeBattleRole, this.fish.id)
            this.node.destroy()
        })
        this.fishBagBtn.node.on(Button.EventType.CLICK, () => {
            const fishBagUI = lobby.instance.addUIWithClickMask("prefab/common/fish-bag", 0, (node) => {
                node.destroy()
                this.fishBag = null
            })
            const pg = fishBagUI.getComponent(PropBag)!
            pg.showAssetsBag(BagType.FishBag, cmm.map2kv(this.fish.assetInfo!.props, (k, v) => {
                return {
                    k2: k.toNumber(),
                    v2: v,
                }
            }), this.fish.id)
            this.fishBag = pg
        })
        this.zoneMapBtn.node.on(Button.EventType.CLICK, () => {
            const zoneMapPlaneNode = lobby.instance.addUIWithClickMask('prefab/common/zone-map-plane', 0, (node) => node.destroy())
            zoneMapPlaneNode.getComponent(ZoneMapPlane)!.init(this.fish.id)
        })
        this.lingGenBox.on(Node.EventType.TOUCH_END, () => {
            const tn = instantiate(this.tipsPrefab)
            lobby.instance.gui.addChild(tn)
            const propDesc = tn.getComponent(PropDesc)!
            propDesc.initLingGen(this.lingGenBox, this.fish.lingGenSkills)
        })
        director.on(GameEvent.userFishRemove, this.removeFish, this)
        director.on(GameEvent.uiUpdateFish, this._updateUI, this)
        director.on(GameEvent.uiUpdateFishBag, this._updateFishBag, this)
    }

    offEvent() {
        director.off(GameEvent.userFishRemove, this.removeFish, this)
        director.off(GameEvent.uiUpdateFish, this._updateUI, this)
        director.off(GameEvent.uiUpdateFishBag, this._updateFishBag, this)
    }

    changeFish(fishId: Long): void {
        const ff = userInfo.fishInfo.loadFishById(fishId)
        if (ff) {
            this.fish = ff;
            this.showBtn = true
            this._updateUI(fishId);
        }
    }

    changeFishDetail(ff: FreshImmortal): void {
        this.fish = ff;
        this.showBtn = false
        this._updateUI(ff.id);
    }

    removeFish(fish: FreshImmortal) {
        if (this.fish.id.eq(fish.id)) {
            this.node.destroy()
        }
    }


    protected onDestroy(): void {
        this.offEvent()
    }

    _updateFishBag(fishId: string): void {
        if (this.fish.id!.neq(fishId) && this.fishBag) {
            this.fishBag.changeAssetsNum(cmm.map2kv(this.fish.assetInfo!.props, (k, v) => {
                return {
                    k2: k.toNumber(),
                    v2: v,
                }
            }))
        }
    }

    _updateUI(fishId: Long) {
        if (this.fish.id!.neq(fishId)) return
        this.zoneId = this.fish.zoneId
        this.head.setHead(fishId, this.fish.baseInfo!.gender, this.fish.baseInfo!.gender, this.fish.masterInfo!.masterId.toString())
        this.nameLb.string = this.fish.baseInfo!.fishName;
        this.masterLabel.node.active = false
        this.genderIcon.spriteFrame = resources.get('textures/ui-base/gender-' + this.fish.baseInfo!.gender + '-icon/spriteFrame', SpriteFrame)
        this.ageLb.string = (Math.ceil((serverTimeHelper.loadServerTime() - (this.fish.baseInfo!.birthAtMs.toNumber())) / 7200000)) + "岁"
        this.talentLb.string = configsHelper.loadTalentName(this.fish.baseInfo!.talent);
        this.talentLb.color = configsHelper.loadTalentColor(this.fish.baseInfo!.talent);
        this.personalityLb.string = configsHelper.loadPersonalityName(this.fish.personalityId)
        this._generateLingGen()

        const finalBI = this.fish.battleInfo!.finalBattleInfo!
        this.fishAttrsDetails.init(finalBI)
        this.attackLabel.string = textUtils.longToTenThousand(finalBI.physicalAttack)
        this.defenceLabel.string = textUtils.longToTenThousand(finalBI.physicalDefense)
        this.recoverLabel.string = textUtils.longToTenThousand(finalBI.normalSelfHealing)
        const specialAttack = finalBI.goldAttack.add(finalBI.woodAttack).add(finalBI.waterAttack).add(finalBI.fireAttack).add(finalBI.earthAttack)
        const specialDefence = finalBI.goldDefense.add(finalBI.woodDefense).add(finalBI.waterDefense).add(finalBI.fireDefense).add(finalBI.earthDefense)
        this.specialAttackLabel.string = textUtils.longToTenThousand(specialAttack)
        this.specialDefenceLabel.string = textUtils.longToTenThousand(specialDefence)

        let maxExp = Math.floor(fishUtils.calcGrowthRequireMoney(this.fish.assetInfo!.level))
        let currentExp = (this.fish.assetInfo!.money ? this.fish.assetInfo!.money.toNumber() : 0)
        let currentHeal = Math.max(this.fish.battleInfo!.currentNormalHealth.toNumber(), 0)
        let currentMp = Math.max(this.fish.battleInfo!.currentMagicPower.toNumber(), 0)
        const maxHealth = maxNormalHealth(this.fish.battleInfo!.finalBattleInfo!)
        const maxMp = maxMagicPower(this.fish.battleInfo!.finalBattleInfo!)
        this.levelLabel.string = configsHelper.loadLevelStr(this.fish.assetInfo!.level)
        this.protectBtn.node.active = this.fish.assetInfo!.level < 10;
        tween(this.hpPb).to(0.5, {progress: currentHeal / maxHealth}, {easing: "circOut"}).start()
        tween(this.mpPb).to(0.5, {progress: currentMp / maxMp}, {easing: "circOut"}).start()
        tween(this.expPb).to(0.5, {progress: currentExp / maxExp}, {easing: "circOut"}).start()

        this.hpLb.string = textUtils.numberToTenThousand(currentHeal) + '/' + textUtils.numberToTenThousand(maxHealth)
        this.mpLb.string = textUtils.numberToTenThousand(currentMp) + '/' + textUtils.numberToTenThousand(maxMp)
        this.expLb.string = textUtils.numberToTenThousand(currentExp) + '/' + textUtils.numberToTenThousand(maxExp)
        // this
        const growthPoint: Map<number, number> = new Map(
            [
                [600001, 0],
                [600002, 0],
                [600003, 0],
                [600004, 0],
                [600005, 0],
            ]
        )
        let totalOffset = 0
        for (let record of this.fish.battleInfo!.growthRecords) {
            totalOffset += record.growthPointMax
            for (let sr of record.growthPoint) {
                let cp = growthPoint.get(sr.propId.toNumber())
                if (!cp) cp = 0
                growthPoint.set(sr.propId.toNumber(), cp + sr.num.toNumber())
            }
        }
        totalOffset = totalOffset / 5
        const jinPoint = growthPoint.get(600001)!
        const liPoint = growthPoint.get(600002)!
        const qiPoint = growthPoint.get(600003)!
        const renPoint = growthPoint.get(600004)!
        const shenPoint = growthPoint.get(600005)!

        const jdn = this.calcDimNum(jinPoint, totalOffset) * (1 + 4 * (this.fish.assetInfo!.level / 100))
        const ldn = this.calcDimNum(liPoint, totalOffset) * (1 + 4 * (this.fish.assetInfo!.level / 100))
        const qdn = this.calcDimNum(qiPoint, totalOffset) * (1 + 4 * (this.fish.assetInfo!.level / 100))
        const rdn = this.calcDimNum(renPoint, totalOffset) * (1 + 4 * (this.fish.assetInfo!.level / 100))
        const sdn = this.calcDimNum(shenPoint, totalOffset) * (1 + 4 * (this.fish.assetInfo!.level / 100))


        this.dimRadarChart.updateData(growthPoint, [jdn, ldn, qdn, rdn, sdn], ['精', '力', '气', '韧', '神'])

        const hsc = configsHelper.loadHairStyle(this.fish.baseInfo!.looks!.hairStyle)
        if (hsc) {
            this.hsLabel.string = hsc!.name
        } else {
            this.hsLabel.string = ''
        }
        const hcc = configsHelper.loadHairColor(this.fish.baseInfo!.looks!.hairColor)
        if (hcc) {
            this.hcLabel.string = hcc!.name
        } else {
            this.hcLabel.string = ''
        }
        if (this.fish.baseInfo!.looks!.leftEye == this.fish.baseInfo!.looks!.rightEye) {
            this.rightEyeColors.node.active = false
            const eyeColor = configsHelper.loadEyeColor(this.fish.baseInfo!.looks!.leftEye)
            if (eyeColor) {
                this.leftEyeColors.string = '瞳色：' + eyeColor!.name
            } else {
                this.leftEyeColors.string = '瞳色：'
            }
        } else {
            this.rightEyeColors.node.active = true
            this.leftEyeColors.node.active = true
            const leftEyeColor = configsHelper.loadEyeColor(this.fish.baseInfo!.looks!.leftEye)
            if (leftEyeColor) {
                this.leftEyeColors.string = '左瞳色：' + leftEyeColor!.name
            } else {
                this.leftEyeColors.string = '左瞳色：'
            }
            const rightEyeColor = configsHelper.loadEyeColor(this.fish.baseInfo!.looks!.rightEye)
            if (rightEyeColor) {
                this.rightEyeColors.string = '右瞳色：' + rightEyeColor!.name
            } else {
                this.rightEyeColors.string = '右瞳色：'
            }
        }
        const sc = configsHelper.loadSkinColor(this.fish.baseInfo!.looks!.skin)
        if (sc) {
            this.skinLabel.string = sc!.name
        } else {
            this.skinLabel.string = ''
        }

        this.peculiarityBox.node.destroyAllChildren()
        for (let psk in this.fish.peculiaritySkills) {
            let pn = instantiate(resources.get("prefab/peculiarity", Prefab)!)
            this.peculiarityBox.node.addChild(pn)
            const peculiarity = pn.getComponent(Peculiarity)!;
            peculiarity.setPeculiarity(this.fish.peculiaritySkills[psk])
        }
        if (this.showBtn) {
            if (this.fish.masterInfo!.masterId == userInfo.loadUid()) {
                this.btnLianhua.active = this.fish.status == FishStatus.dead;
                this.btnjihuo.active = this.fish.status == FishStatus.sleep;
                this.chenshui.active = (this.fish.status == FishStatus.alive) || !this.fish.status;
                this.zoneMapBtn.node.active = (this.fish.status == FishStatus.alive) || !this.fish.status;
            } else {
                this.btnLianhua.active = false;
                this.btnjihuo.active = false;
                this.chenshui.active = false;
                this.zoneMapBtn.node.active = false
                this.fishBagBtn.node.active = false
                this.btnChange.active = false
            }
        } else {
            this.btnLianhua.active = false;
            this.btnjihuo.active = false;
            this.chenshui.active = false;
            this.zoneMapBtn.node.active = false
            this.fishBagBtn.node.active = false
            this.btnChange.active = false
            if (this.fish.masterInfo?.masterName) {
                this.masterLabel.node.active = true
                this.masterLabel.string = '「' + this.fish.masterInfo!.masterName + '宗」'
            }
        }
    }

    private _generateLingGen() {
        this.firstLingGen.active = false
        this.secondLingGen.active = false
        if (this.fish.lingGenSkills.size <= 0) return
        this.firstLingGen.active = true
        let tps = cmm.map2array(this.fish.lingGenSkills, (k, v) => new Tuple2(k, v))
        tps = tps.sort((o1, o2) => o2.t2.comp(o1.t2))
        this.firstLingGen.getComponent(Sprite)!.spriteFrame = resources.get(`/textures/ling-gen/ling-gen-${tps[0].t1}-icon/spriteFrame`, SpriteFrame)!
        const scale1 = 0.8 + tps[0].t2.toNumber() * 0.4 / 10000
        this.firstLingGen.scale = new Vec3(scale1, scale1, 1)
        if (tps.length > 1) {
            this.secondLingGen.active = true
            this.secondLingGen.getComponent(Sprite)!.spriteFrame = resources.get(`/textures/ling-gen/ling-gen-${tps[1].t1}-icon/spriteFrame`, SpriteFrame)!
            const scale2 = 0.8 + tps[1].t2.toNumber() * 0.4 / 10000
            this.secondLingGen.scale = new Vec3(scale2, scale2, 1)
        }
    }

    calcDimNum(point: number, offset: number) {
        return point <= offset ? (point * 0.15 / offset) : (0.15 + (point - offset) * 0.05 / (offset * 4))
    }

    update(deltaTime: number) {

    }
}


